From 5e31df515ce082b1caa526f7a35fd7c53099e918 Mon Sep 17 00:00:00 2001 From: robertl Date: Wed, 9 Apr 2003 13:09:36 +0000 Subject: [PATCH] Add copilot support. Courtesy Paul Tomblin. --- gpsbabel/Makefile | 3 +- gpsbabel/README | 13 +++ gpsbabel/copilot.c | 213 +++++++++++++++++++++++++++++++++++++++ gpsbabel/defs.h | 6 ++ gpsbabel/jeeps/gpsmath.c | 4 +- gpsbabel/util.c | 51 ++++++++++ gpsbabel/vecs.c | 7 ++ 7 files changed, 294 insertions(+), 3 deletions(-) create mode 100644 gpsbabel/copilot.c diff --git a/gpsbabel/Makefile b/gpsbabel/Makefile index 81de1b0f4..430606fdd 100644 --- a/gpsbabel/Makefile +++ b/gpsbabel/Makefile @@ -3,7 +3,7 @@ CFLAGS=$(EXTRA_CFLAGS) -g -Icoldsync INSTALL_TARGETDIR=/usr/local/ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o \ - gpsutil.o pcx.o cetus.o gpspilot.o magnav.o \ + gpsutil.o pcx.o cetus.o copilot.o gpspilot.o magnav.o \ psp.o holux.o garmin.o tmpro.o tpg.o \ xcsv.o gcdb.o tiger.o internal_styles.o @@ -70,6 +70,7 @@ release: ncftpput -u anonymous upload.sf.net /incoming /tmp/gpsbabel-$(VERSIOND).tar.gz /tmp/gpsbabel-$(VERSIOND).zip cetus.o: cetus.c defs.h queue.h coldsync/palm.h coldsync/pdb.h +copilot.o: copilot.c defs.h queue.h coldsync/palm.h coldsync/pdb.h csv.o: csv.c defs.h queue.h csv_util.h csv_util.o: csv_util.c defs.h queue.h csv_util.h dna.o: dna.c defs.h queue.h csv_util.h diff --git a/gpsbabel/README b/gpsbabel/README index 031af3670..0db94a679 100644 --- a/gpsbabel/README +++ b/gpsbabel/README @@ -293,6 +293,19 @@ THE FORMATS http://vip.hyperusa.com/~dougs/geocachingdb/geocachingdb.htm + CoPilot Flight Planner for Palm OS + + This code is mostly intended to convert CoPilot databases into + other formats. I don't think you should use this to write + CoPilot databases, although the code is there, mostly because + GPSBabel doesn't convert magnetic declination values. + + Questions, bug reports, etc, to ptomblin at xcski.com + + + http://xcski.com/~ptomblin/CoPilot/ + http://navaid.com/CoPilot/ + DATA FILTERS diff --git a/gpsbabel/copilot.c b/gpsbabel/copilot.c new file mode 100644 index 000000000..f36a321d6 --- /dev/null +++ b/gpsbabel/copilot.c @@ -0,0 +1,213 @@ +/* + Read and write CoPilot files. + + Copyright (C) 2002 Paul Tomblin, ptomblin@xcski.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "coldsync/palm.h" +#include "coldsync/pdb.h" +#include "math.h" +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +static double conv = 180.0 / M_PI; + +#define MYNAME "CoPilot Waypoint" +#define MYTYPE 0x77617970 /* wayp */ +#define MYCREATOR 0x47584255 /* GXBU */ + + +struct record { + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + pdb_double elevation; /* feet */ + char flags; +}; + +static FILE *file_in; +static FILE *file_out; +static const char *out_fname; +struct pdb *opdb; +struct pdb_record *opdb_rec; + +static void +rd_init(const char *fname, const char *args) +{ + file_in = fopen(fname, "rb"); + if (file_in == NULL) { + fatal(MYNAME ": Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(file_in); +} + +static void +wr_init(const char *fname, const char *args) +{ + file_out = fopen(fname, "wb"); + out_fname = fname; + if (file_out == NULL) { + fatal(MYNAME ": Cannot open %s for writing\n", fname); + } +} + +static void +wr_deinit(void) +{ + fclose(file_out); +} + +static void +data_read(void) +{ + struct record *rec; + struct pdb *pdb; + struct pdb_record *pdb_rec; + + if (NULL == (pdb = pdb_Read(fileno(file_in)))) { + fatal(MYNAME ": pdb_Read failed\n"); + } + + if ((pdb->creator != MYCREATOR) || (pdb->type != MYTYPE)) { + fatal(MYNAME ": Not a CoPilot file.\n"); + } + + for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata; + + wpt_tmp = xcalloc(sizeof(*wpt_tmp),1); + + rec = (struct record *) pdb_rec->data; + wpt_tmp->position.longitude.degrees = + -pdb_read_double(&rec->longitude) * conv; + wpt_tmp->position.latitude.degrees = + pdb_read_double(&rec->latitude) * conv; + wpt_tmp->position.altitude.altitude_meters = + pdb_read_double(&rec->elevation) * .3048; + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } + free_pdb(pdb); +} + + +static void +copilot_writewpt(const waypoint *wpt) +{ + struct record *rec; + static int ct = 0; + char *vdata; + + rec = xcalloc(sizeof(*rec)+1141,1); + + pdb_write_double(&rec->latitude, wpt->position.latitude.degrees / conv); + pdb_write_double(&rec->longitude, + -wpt->position.longitude.degrees / conv); + pdb_write_double(&rec->elevation, + wpt->position.altitude.altitude_meters / .3048); + pdb_write_double(&rec->magvar, 0); + + vdata = (char *)rec + sizeof(*rec); + if ( wpt->shortname ) { + strncpy( vdata, wpt->shortname, 10 ); + vdata[9] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + if ( wpt->description ) { + strncpy( vdata, wpt->description, 100 ); + vdata[99] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + if ( wpt->notes ) { + strncpy( vdata, wpt->notes, 1000 ); + vdata[999] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + opdb_rec = new_Record (0, 2, ct++, vdata-(char *)rec, (const ubyte *)rec); + + if (opdb_rec == NULL) { + fatal(MYNAME ": libpdb couldn't create record\n"); + } + + if (pdb_AppendRecord(opdb, opdb_rec)) { + fatal(MYNAME ": libpdb couldn't append record\n"); + } + xfree(rec); +} + +static void +data_write(void) +{ + queue *elem, *tmp; + + if (NULL == (opdb = new_pdb())) { + fatal (MYNAME ": new_pdb failed\n"); + } + + strncpy(opdb->name, out_fname, PDB_DBNAMELEN); + opdb->name[PDB_DBNAMELEN-1] = 0; + opdb->attributes = PDB_ATTR_BACKUP; + opdb->ctime = opdb->mtime = time(NULL) + 2082844800U; + opdb->type = MYTYPE; + opdb->creator = MYCREATOR; + opdb->version = 0; + + waypt_disp_all(copilot_writewpt); + + pdb_Write(opdb, fileno(file_out)); +} + + +ff_vecs_t copilot_vecs = { + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, +}; diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index 5107b2dc5..77970284f 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -344,6 +344,10 @@ typedef struct { unsigned char data[2]; } pdb_16; +typedef struct { + unsigned char data[8]; +} pdb_double; + /* * Protypes for Endianness helpers. */ @@ -356,6 +360,8 @@ void be_write16(void *pp, unsigned i); void be_write32(void *pp, unsigned i); void le_write16(void *pp, unsigned i); void le_write32(void *pp, unsigned i); +double pdb_read_double(void *p); +void pdb_write_double(void *pp, double d); /* * A constant for unknown altitude. It's tempting to just use zero diff --git a/gpsbabel/jeeps/gpsmath.c b/gpsbabel/jeeps/gpsmath.c index 35e9da385..c5c623335 100644 --- a/gpsbabel/jeeps/gpsmath.c +++ b/gpsbabel/jeeps/gpsmath.c @@ -217,7 +217,7 @@ void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg) double GPS_Math_Metres_To_Feet(double v) { - return v*(double)2.7432; + return v/0.3048; } @@ -233,7 +233,7 @@ double GPS_Math_Metres_To_Feet(double v) double GPS_Math_Feet_To_Metres(double v) { - return v/(double)2.7432; + return v * 0.3048; } diff --git a/gpsbabel/util.c b/gpsbabel/util.c index de40fc344..359e6f2c2 100644 --- a/gpsbabel/util.c +++ b/gpsbabel/util.c @@ -372,3 +372,54 @@ get_cache_icon(const waypoint *waypointp) } return NULL; } + +static int swapit = -1; + +static int doswap() +{ + if (swapit < 0) + { + /* On Intel, Vax and MIPs little endian, -1.0 maps to the bytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f and on Motorola, + SPARC, ARM, and PowerPC, it maps to + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00. + */ + double d = 1.0; + char c[8]; + memcpy(c, &d, 8); + swapit = (c[0] == 0); + } + return swapit; +} + +double +pdb_read_double(void* ptr) +{ + double ret; + char r[8]; + int i; + doswap(); /* make sure swapit is initialized */ + for (i = 0; i < 8; i++) + { + int j = (swapit)?(7-i):i; + r[i] = ((char*)ptr)[j]; + } + memcpy(&ret, r, 8); + return ret; +} + +void +pdb_write_double(void* ptr, double d) +{ + char r[8]; + int i; + + memcpy(r, &d, 8); + doswap(); /* make sure swapit is initialized */ + for (i = 0; i < 8; i++) + { + int j = (swapit)?(7-i):i; + *(char*)ptr++ = r[j]; + } + return; +} diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index 9db8180ee..c67cff2c9 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -40,6 +40,7 @@ extern ff_vecs_t tiger_vecs; extern ff_vecs_t pcx_vecs; extern ff_vecs_t cetus_vecs; extern ff_vecs_t gpspilot_vecs; +extern ff_vecs_t copilot_vecs; extern ff_vecs_t psp_vecs; extern ff_vecs_t garmin_vecs; extern ff_vecs_t holux_vecs; @@ -112,6 +113,12 @@ vecs_t vec_list[] = { "Cetus for Palm/OS", NULL }, + { + &copilot_vecs, + "copilot", + "CoPilot Flight Planner for Palm/OS", + NULL + }, { &gpspilot_vecs, "gpspilot", -- 2.30.2